package com.atguigu.ssyx.cart.service.impl;

import com.atguigu.ssyx.cart.service.CartInfoService;
import com.atguigu.ssyx.client.product.ProductFeignClient;
import com.atguigu.ssyx.common.constant.RedisConst;
import com.atguigu.ssyx.common.exception.SsyxException;
import com.atguigu.ssyx.common.result.ResultCodeEnum;
import com.atguigu.ssyx.enums.SkuType;
import com.atguigu.ssyx.model.order.CartInfo;
import com.atguigu.ssyx.model.product.SkuInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @作者:胡树苑
 * @时间:2025/9/22 13:47
 */
@Service
public class CartInfoServiceImpl implements CartInfoService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Override
    public void addToCart(Long userId, Long skuId, Integer skuNum) {
        //1.因为购物车数据都是存储到redis里面
        //从redis里面根据key获取数据，这个key包含userId
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String,String, CartInfo> hashOperations =
                redisTemplate.boundHashOps(cartKey);
        //2根据第一步查询出来的结果，得到是skuid+skunum关系
        CartInfo cartInfo = null;
        //目的:判断是否是第一次添加这个商品到购物车
        //进行判断，判断结果里面是否有skuid
        if(hashOperations.hasKey(skuId.toString())){
            //3如果结果包含了skuId说明不是第一次添加
            //3.1根据skuid获取到对应的数量，更新数量
             cartInfo = hashOperations.get(skuId.toString());
             //把购物车存在商品之前数量 获取数量 在进行数量更新操作
            Integer newSkuNum = cartInfo.getSkuNum() + skuNum;
            if(newSkuNum<1){
                return;
            }
            cartInfo.setSkuNum(newSkuNum);
            cartInfo.setCurrentBuyNum(newSkuNum);
            //判断商品数量不能大于限购数量
            Integer perLimit = cartInfo.getPerLimit();
            if(newSkuNum>perLimit){
                throw  new SsyxException(ResultCodeEnum.SKU_LIMIT_ERROR);
            }
            //跟新其他值
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        }else{
            //4如果结果没有包含skuid表示是第一次添加
            //4.1直接添加
            skuNum =1;
            //封装cartInfo
            cartInfo = new CartInfo();
            //获取sku信息  远程调用根据skuid获取sku信息
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            if(skuInfo==null){
                throw  new SsyxException(ResultCodeEnum.DATA_ERROR);
            }
            //封装cartInfo对象
            cartInfo.setSkuId(skuId);
            cartInfo.setCategoryId(skuInfo.getCategoryId());
            cartInfo.setSkuType(skuInfo.getSkuType());
            cartInfo.setIsNewPerson(skuInfo.getIsNewPerson());
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCurrentBuyNum(skuNum);
            cartInfo.setSkuType(SkuType.COMMON.getCode());
            cartInfo.setPerLimit(skuInfo.getPerLimit());
            cartInfo.setImgUrl(skuInfo.getImgUrl());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setWareId(skuInfo.getWareId());
            cartInfo.setIsChecked(1);
            cartInfo.setStatus(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }
        //5更新redis缓存
        hashOperations.put(skuId.toString(),cartInfo);
        //6设置有效时间
        this.setCartKeyExpire(cartKey);
    }
    //根据skuid删除购物车
    @Override
    public void deleteCart(Long skuId, Long userId) {
        BoundHashOperations<String,String,CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        if(hashOperations.hasKey(skuId.toString())){
            hashOperations.delete(skuId.toString());
        }
    }
    //清空购物车
    @Override
    public void deleteAllCart(Long userId) {
        BoundHashOperations<String,String,CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        List<CartInfo> cartInfoList = hashOperations.values();
        for(CartInfo cartInfo : cartInfoList){
            hashOperations.delete(cartInfo.getSkuId().toString());
        }
    }
    //批量删除购物车 多个skuid
    @Override
    public void batchDeleteCart(List<Long> skuIdList, Long userId) {
        BoundHashOperations<String,String,CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        skuIdList.forEach(skuId -> hashOperations.delete(skuId.toString()));
    }
    //查询购物车列表
    @Override
    public List<CartInfo> getCartList(Long userId) {
        //判断userid是否为空
        List<CartInfo> cartInfoList = new ArrayList<>();
        if(StringUtils.isEmpty(userId)){
            return cartInfoList;
        }
        //从redis里面获取购物车的数据
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        cartInfoList = boundHashOperations.values();
        //根据时间降序
        if(!CollectionUtils.isEmpty(cartInfoList)){
            //根据商品添加时间，降序
            cartInfoList.sort(new Comparator<CartInfo>() {
                @Override
                public int compare(CartInfo o1, CartInfo o2) {
                    return o1.getCreateTime().compareTo(o2.getCreateTime());
                }
            });
        }
        return cartInfoList;

    }

    @Override
    public void checkCart(Long userId, Integer isChecked, Long skuId) {
        //获取redis的key
        String cartKey = this.getCartKey(userId);
        //根据cartkey获取field-value
        BoundHashOperations<String,String,CartInfo> boundHashOperations
                = redisTemplate.boundHashOps(cartKey);
       //根据field(skuid) 获取value(CartInfo)
        CartInfo cartInfo = boundHashOperations.get(skuId.toString());
        if(cartInfo!=null){
            cartInfo.setIsChecked(isChecked);
            //跟新
            boundHashOperations.put(skuId.toString(),cartInfo);
            //设置key过期时间
            this.setCartKeyExpire(cartKey);
        }
    }

    @Override
    public void checkAllCart(Long userId, Integer isChecked) {
        //获取redis的key
        String cartKey = this.getCartKey(userId);
        //根据cartkey获取field-value
        BoundHashOperations<String,String,CartInfo> boundHashOperations
                = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            });
            this.setCartKeyExpire(cartKey);
        }
    }

    @Override
    public void batchCheckCart(List<Long> skuIdList, Long userId, Integer isChecked) {
        String cartKey = getCartKey(userId);
        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        skuIdList.forEach(skuId -> {
            CartInfo cartInfo = hashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
        });
        this.setCartKeyExpire(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations =
                redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOperations.values();
        List<CartInfo> newcartInfoList = cartInfoList.stream().filter(
                cartInfo -> cartInfo.getIsChecked().intValue() == 1
        ).collect(Collectors.toList());
        return newcartInfoList;
    }

    @Override
    public void deleteCartChecked(Long userId) {
        //根据用户id查询选中的购物车记录
        List<CartInfo> cartInfoList = this.getCartCheckedList(userId);
        //查询list集合，得到每一个skuId集合
        List<Long> skuIdList = cartInfoList.stream().map(
                item -> item.getSkuId()
        ).collect(Collectors.toList());
        //构建redis的key的值
        String cartKey = this.getCartKey(userId);
        //根据key查询filed-value的结构
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        skuIdList.forEach(skuId -> {
            boundHashOperations.delete(skuId.toString());
        });
    }

    //设置 key过期时间
    private void setCartKeyExpire(String Key) {
        redisTemplate.expire(Key,RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS);
    }

    //返回购物车在redis的key
    //试例:user:userId:cart
    private String getCartKey(Long userId) {
      return RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
    }
}
